#include <sys/types.h>
#include <sys/socket.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <errno.h>
// #include <stdlib.h> // Duplicate include removed
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h> // Added for close() and sleep()

#define PORT 8888 // Define port consistently

int main(int argc, char **argv)
{
    int sock;
    socklen_t addr_len;        // Use socklen_t
    ssize_t len;               // Use ssize_t for sendto/recvfrom return
    char buff[128];            // Consistent naming
    struct sockaddr_in s_addr; // Server address

    if ((sock = socket(AF_INET, SOCK_DGRAM, 0)) == -1)
    { // Correct check: == -1
        perror("socket create failed");
        exit(1);
    }
    else
    {
        printf("socket create successful.\n");
    }

    memset(&s_addr, 0, sizeof(s_addr)); // Zero out struct
    s_addr.sin_family = AF_INET;
    s_addr.sin_port = htons(PORT); // Use defined PORT
    // memset(s_addr.sin_zero, '\0', sizeof(s_addr.sin_zero)); // sin_zero is obsolete, memset covers it

    // Argument check: Need server IP and data
    if (argc < 3)
    { // Correct check: need program name, IP, data
        // Corrected usage message
        printf("Usage: %s <server_ip> <data_to_send>\n", argv[0]);
        close(sock);
        exit(1); // Use exit(1) for error exit
    }

    // Set server IP from argv[1]
    if (inet_aton(argv[1], &s_addr.sin_addr) == 0)
    {
        fprintf(stderr, "Invalid server IP address: %s\n", argv[1]);
        close(sock);
        exit(1);
    }

    // Copy data to send from argv[2]
    strncpy(buff, argv[2], sizeof(buff) - 1);
    buff[sizeof(buff) - 1] = '\0';

    addr_len = sizeof(s_addr);
    len = sendto(sock, buff, strlen(buff), 0, (struct sockaddr *)&s_addr, addr_len);

    if (len < 0)
    {
        perror("sendto error."); // perror adds newline
        close(sock);
        exit(1);
    }

    printf("Sent: %s to %s:%d\n", buff, argv[1], PORT);

    // Prepare to receive response
    memset(buff, 0, sizeof(buff)); // Clear buffer
    addr_len = sizeof(s_addr);     // Reset addr_len before recvfrom

    len = recvfrom(sock, buff, sizeof(buff) - 1, 0, (struct sockaddr *)&s_addr, &addr_len);

    if (len < 0)
    {
        perror("recvfrom error."); // perror adds newline
        close(sock);
        exit(1);
    }

    buff[len] = '\0'; // Null-terminate
    printf("receive from server %s\n", buff);

    close(sock);
    return 0;
}